﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using System.Collections;
using MetadataBasedConfigArch.Framework;
using System.Web.UI;
using System.Reflection;
using System.ComponentModel;

namespace MetadataBasedConfigArch.Web.Controls
{
    public class CTXGridView : GridView
    {
        #region Ctor

        public CTXGridView()
            : base()
        {
            AutoGenerateExtendPropertiesColumn = false;
            AutoGenerateColumnsAfter = -1;
        }

        #endregion

        #region Fields

        protected List<string> _allExtendPropertiesColumnsName
        {
            get
            {
                return (ViewState["allExtendPropertiesColumnsName"]??(new List<string>())) as List<string>;
            }
            set
            {
                ViewState["allExtendPropertiesColumnsName"] = value;
            }
        }

        #endregion

        #region Properties

        public bool AutoGenerateExtendPropertiesColumn { get; set; }

        public int AutoGenerateColumnsAfter { get; set; }

        public string ExtendPropertiesDataField { get; set; }

        #endregion
         
        protected override ICollection CreateColumns(PagedDataSource dataSource, bool useDataSource)
        {
            ICollection collection = base.CreateColumns(dataSource, useDataSource);            

            if (AutoGenerateExtendPropertiesColumn)
            {
                ArrayList list = new ArrayList();

                ICollection extendPropertiesCollection = useDataSource?CreateExtendPropertiesColumns(dataSource):CreateExtendPropertiesColumns(_allExtendPropertiesColumnsName);

                ArrayList list1 = new ArrayList();
                foreach (var c in collection)
                {
                    list1.Add(c);
                }

                ArrayList list2 = new ArrayList();
                if (extendPropertiesCollection != null)
                {
                    foreach (var c in extendPropertiesCollection)
                    {
                        list2.Add(c);
                    }
                }

                int copyFrom = AutoGenerateColumnsAfter < list1.Count ? AutoGenerateColumnsAfter : list1.Count - 1;
                copyFrom = copyFrom >= 0 ? copyFrom : -1;

                for (int i = 0; i <= copyFrom; i++)
                {
                    list.Add(list1[i]);
                }
                
                list.AddRange(list2.ToArray());

                for (int i = copyFrom + 1; i < list1.Count; i++)
                {
                    list.Add(list1[i]);
                }
                return list;
            }
            return collection; 
        }

        protected virtual ICollection CreateExtendPropertiesColumns(List<string> allExtendPropertiesColumnsName)
        {
            ArrayList array = new ArrayList();
            if (allExtendPropertiesColumnsName != null)
            {
                foreach (string name in allExtendPropertiesColumnsName)
                {
                    ExtBouldField bouldField = new ExtBouldField();
                    bouldField.UseMethodBinding = true;
                    bouldField.MethodName = "GetConfigurableInfo";
                    bouldField.MethodParam = name;
                    bouldField.HeaderText = name;
                    array.Add(bouldField); 
                }
            }
            return array;
        }
        protected virtual ICollection CreateExtendPropertiesColumns(PagedDataSource dataSource)
        {
            ArrayList array = new ArrayList();
            _allExtendPropertiesColumnsName = new List<string>();
            if (dataSource!=null && dataSource.DataSourceCount > 0 && !String.IsNullOrEmpty(ExtendPropertiesDataField))
            { 
                var enumerator = dataSource.DataSource.GetEnumerator();
                enumerator.Reset();
                if (enumerator.MoveNext())
                {
                    object firstData = enumerator.Current;
                    if (firstData != null)
                    {
                        PropertyDescriptor extendPropertiesDesc = TypeDescriptor.GetProperties(firstData).Find(ExtendPropertiesDataField, false);
                        if (extendPropertiesDesc != null && typeof(IEnumerable<KeyValuePair<string, object>>).IsAssignableFrom(extendPropertiesDesc.PropertyType))
                        {
                            IEnumerable<KeyValuePair<string, object>> extendProperties = (IEnumerable<KeyValuePair<string, object>>)extendPropertiesDesc.GetValue(firstData);
                            if (extendProperties != null)
                            {
                                foreach (var exProperty in extendProperties)
                                {
                                    ExtBouldField bouldField = new ExtBouldField();
                                    bouldField.UseMethodBinding = true;
                                    bouldField.MethodName = "GetConfigurableInfo";
                                    bouldField.MethodParam = exProperty.Key;
                                    bouldField.HeaderText = exProperty.Key;
                                    array.Add(bouldField);
                                    _allExtendPropertiesColumnsName.Add(exProperty.Key);
                                }
                            }
                        }
                    }
                } 
            }
            return array;
        } 
    }

}